using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using TEngine;
using System;
using DG.Tweening;
using System.Collections.Generic;
using UnityEngine.EventSystems;

namespace GameLogic
{
    [Window(UILayer.UI, fullScreen: true)]
    public class Pan_GameZeroSumDrag : UIWindow
    {
        #region UI Components
        [SerializeField] private Button _btnClose; // 关闭按钮
        [SerializeField] private Button m_btnHit; // 提示按钮
        [SerializeField] private RectTransform _rectMatrix; // 矩阵容器
        private MatrixCtrl _matrixCtrl; // 矩阵控制器
        private WindowAnimationHelper _animationHelper; // 窗口动画辅助
        private DragHandler _dragHandler; // 拖拽处理组件
        #endregion

        #region Game Logic Fields
        private System.Random _random = new System.Random(); // 随机数生成器
        private HashSet<int> _currentValues = new HashSet<int>(); // 当前棋盘数值集合
        private Vector2Int? _startGridPos; // 拖拽起始网格坐标
        private List<Vector2Int> _selectedCells = new List<Vector2Int>(); // 已选中的单元格坐标
        private Vector2Int _lastProcessedPos; // 最后处理的网格位置
        private List<Vector2Int[]> _hintPairs = new List<Vector2Int[]>(); // 存储可消除的提示对
        private float _lastHintTime; // 上次提示时间
        private const float HINT_DURATION = 5f; // 提示持续时间
        #endregion

        #region Lifecycle Methods
        protected override void BindMemberProperty()
        {
            _btnClose = FindChildComponent<Button>("m_btnClose");
            m_btnHit = FindChildComponent<Button>("m_btnHit");
            _rectMatrix = FindChildComponent<RectTransform>("GameView/m_rectMatrix");
            InitializeMatrixCtrl();
            
            _animationHelper = new WindowAnimationHelper(this);
            _dragHandler = DragHandler.Get(gameObject);
        }

        protected override void RegisterEvent()
        {
            _btnClose.onClick.AddListener(OnClose);
            m_btnHit.onClick.AddListener(CheckHint);
            _dragHandler.onBeginDrag.AddListener(OnBeginDrag);
            _dragHandler.onDrag.AddListener(OnDrag);
            _dragHandler.onEndDrag.AddListener(OnEndDrag);
        }

        protected override void OnCreate()
        {
            _animationHelper.Initialize();
            InitializeGameBoard();
        }

        protected override async void OnRefresh()
        {
            await _animationHelper.PlayOpenAnimation();
        }

        protected override void OnDestroy()
        {
            _animationHelper.Cleanup();
            _dragHandler.onBeginDrag.RemoveAllListeners();
            _dragHandler.onEndDrag.RemoveAllListeners();
            _dragHandler.onDrag.RemoveAllListeners();       
            _btnClose.onClick.RemoveAllListeners(); 
            base.OnDestroy();
        }
        #endregion

        #region Core Game Logic
        /// <summary>
        /// 初始化游戏棋盘
        /// 1. 生成可解的数字布局
        /// 2. 初始化矩阵控制器
        /// 3. 创建所有单元格并初始化数值
        /// </summary>
        private void InitializeGameBoard()
        {
            var numbers = GenerateSolvableGrid(8 * 8);
            _matrixCtrl.Initialize<CellCtrl_ZeroSum>(8, 8, _rectMatrix, "CellCtrl_ZeroSum");
            
            var cells = _matrixCtrl.GetAllCells<CellCtrl_ZeroSum>();
            for (int i = 0; i < cells.Length; i++)
            {
                if (cells[i] != null)
                {
                    cells[i].InitializeValue(numbers[i]);
                    _currentValues.Add(numbers[i]);
                }
            }
        }

        /// <summary>
        /// 生成保证有解的棋盘数据
        /// 算法步骤：
        /// 1. 生成成对的相反数保证基本解
        /// 2. 填充随机数并保证成对出现
        /// 3. 使用Fisher-Yates算法洗牌
        /// </summary>
        /// <param name="size">需要生成的数字总数</param>
        /// <returns>包含可解数字的列表</returns>
        private List<int> GenerateSolvableGrid(int size)
        {
            var numbers = new List<int>();
            
            // 保证至少有一对相反数
            int pairCount = Mathf.Max(2, size);
            for (int i = 0; i < pairCount; i++)
            {
                int val = _random.Next(1, 1);
                numbers.Add(val);
                numbers.Add(-val);
            }

            // 填充剩余位置并随机打乱
            FillAndShuffleNumbers(numbers, size);
            return numbers.GetRange(0, size);
        }

        /// <summary>
        /// 填充并打乱数字数组
        /// </summary>
        private void FillAndShuffleNumbers(List<int> numbers, int targetSize)
        {
            while (numbers.Count < targetSize)
            {
                int val = _random.Next(1, 10);
                numbers.Add(val);
                numbers.Add(_random.NextDouble() > 0.5 ? val : -val);
            }

            // Fisher-Yates洗牌算法
            for (int i = numbers.Count - 1; i > 0; i--)
            {
                int randomIndex = _random.Next(i + 1);
                (numbers[i], numbers[randomIndex]) = (numbers[randomIndex], numbers[i]);
            }
        }

        /// <summary>
        /// 检查当前棋盘是否有解
        /// 实现逻辑：
        /// 1. 统计所有数值出现次数
        /// 2. 检查是否存在相反数对
        /// </summary>
        /// <returns>是否存在可消除组合</returns>
        public bool HasSolution()
        {
            var valueCount = new Dictionary<int, int>();
            var cells = _matrixCtrl.GetAllCells<CellCtrl_ZeroSum>();
            
            foreach (var cell in cells)
            {
                if (cell == null) continue;

                int value = cell.Value;
                if (valueCount.ContainsKey(-value) && valueCount[-value] > 0)
                {
                    return true;
                }
                
                valueCount[value] = valueCount.ContainsKey(value) ? valueCount[value] + 1 : 1;
            }
            return false;
        }
        #endregion

        #region Drag Handling
        /// <summary>
        /// 拖拽开始处理
        /// 主要职责：
        /// - 初始化拖拽状态
        /// - 检查动画状态
        /// </summary>
        private void OnBeginDrag(Vector3 arg0, PointerEventData arg1)
        {
            if (_matrixCtrl.IsAnimating()) return;
        }

        /// <summary>
        /// 拖拽过程处理
        /// 核心功能：
        /// 1. 转换屏幕坐标到网格坐标
        /// 2. 处理拖拽路径
        /// 3. 更新选中状态
        /// </summary>
        private void OnDrag(Vector3 arg0, PointerEventData arg1)
        {
            if (_matrixCtrl.IsAnimating()) return;
            
            if (!_matrixCtrl.ScreenToGrid(arg1.position, out var currentPos)) return;

            _startGridPos ??= currentPos;
            ProcessDragPath(currentPos);
        }

        /// <summary>
        /// 拖拽结束处理
        /// 主要逻辑：
        /// 1. 检查消除条件
        /// 2. 重置选中状态
        /// 3. 检查棋盘可解性
        /// 4. 无解时重新生成棋盘
        /// </summary>
        private void OnEndDrag(Vector3 arg0, PointerEventData arg1)
        {
            if (_matrixCtrl.IsAnimating()) return;
            
            CheckAndProcessElimination();
            ResetSelection();
            
            if (!HasSolution())
            {
                Log.Info("需要重新生成棋盘...");
                InitializeGameBoard();
            }
        }
        #endregion

        #region Hint System
        /// <summary>
        /// 查找所有可消除的单元格对
        /// </summary>
        private void FindAllHintPairs()
        {
            _hintPairs.Clear();
            var valuePositions = new Dictionary<int, List<Vector2Int>>();
            var cells = _matrixCtrl.GetAllCells<CellCtrl_ZeroSum>();
            
            // 收集所有数值的位置
            foreach (var cell in cells)
            {
                if (cell == null) continue;
                
                if (!valuePositions.ContainsKey(cell.Value))
                {
                    valuePositions[cell.Value] = new List<Vector2Int>();
                }
                valuePositions[cell.Value].Add(cell.CurrentPos);
            }

            // 查找互为相反数的组合
            foreach (var kvp in valuePositions)
            {
                int targetValue = -kvp.Key;
                if (valuePositions.TryGetValue(targetValue, out var targetPositions))
                {
                    foreach (var pos1 in kvp.Value)
                    {
                        foreach (var pos2 in targetPositions)
                        {
                            if (pos1 != pos2 && IsAdjacent(pos1, pos2))
                            {
                                _hintPairs.Add(new[] { pos1, pos2 });
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 显示提示效果
        /// </summary>
        private void ShowHint()
        {
            if (_hintPairs.Count == 0) return;
            
            // 随机选择一个提示对
            var randomPair = _hintPairs[_random.Next(_hintPairs.Count)];
            foreach (var pos in randomPair)
            {
                var cell = _matrixCtrl.GetCell<CellCtrl_ZeroSum>(pos);
                cell?.SetCellState(CellCtrl_ZeroSum.CellState.Hint);
            }
            
            _lastHintTime = Time.time;
        }

        /// <summary>
        /// 清除提示效果
        /// </summary>
        private void ClearHints()
        {
            foreach (var cell in _matrixCtrl.GetAllCells<CellCtrl_ZeroSum>())
            {
                if (cell?.GetCurrentState() == CellCtrl_ZeroSum.CellState.Hint)
                {
                    cell.SetCellState(CellCtrl_ZeroSum.CellState.Normal);
                }
            }
        }

        private void CheckHint()
        {
            if (Time.time - _lastHintTime > HINT_DURATION)
            {
                ClearHints();
                FindAllHintPairs();
                ShowHint();
            }
        }
        #endregion

        #region Helper Methods
        private void InitializeMatrixCtrl()
        {
            if (!typeof(CellCtrl_ZeroSum).IsSubclassOf(typeof(CellCtrl))) 
            {
                Log.Error($"{nameof(CellCtrl_ZeroSum)}未继承自CellCtrl基类");
                return;
            }

            _matrixCtrl = _rectMatrix.gameObject.GetOrAddComponent<MatrixCtrl>();
            if (_matrixCtrl == null)
            {
                Log.Error($"MatrixCtrl组件添加失败\n" +
                        $"父物体{_rectMatrix.name}是否激活\n" +
                        $"资源路径是否正确");
            }
        }

        /// <summary>
        /// 重置选中状态
        /// </summary>
        private void ResetSelection()
        {
            _startGridPos = null;
            _selectedCells.Clear();
            UpdateSelectionVisual();
        }

        /// <summary>
        /// 更新选中状态显示
        /// </summary>
        private void UpdateSelectionVisual()
        {
            foreach (var cell in _matrixCtrl.GetAllCells<CellCtrl_ZeroSum>())
            {
                if (cell?.GetCurrentState() == CellCtrl_ZeroSum.CellState.Selected)
                {
                    cell.SetCellState(CellCtrl_ZeroSum.CellState.Normal);
                }
            }

            foreach (var pos in _selectedCells)
            {
                var cell = _matrixCtrl.GetCell<CellCtrl_ZeroSum>(pos);
                cell?.SetCellState(CellCtrl_ZeroSum.CellState.Selected);
            }
        }

        /// <summary>
        /// 检查两个网格坐标是否相邻（仅上下左右）
        /// </summary>
        private bool IsAdjacent(Vector2Int a, Vector2Int b)
        {
            int dx = Mathf.Abs(a.x - b.x);
            int dy = Mathf.Abs(a.y - b.y);
            // 仅允许横向或纵向相邻（排除对角线）
            return (dx == 1 && dy == 0) || (dx == 0 && dy == 1);
        }

        /// <summary>
        /// 处理拖拽路径
        /// </summary>
        private void ProcessDragPath(Vector2Int currentPos)
        {
            if (!_startGridPos.HasValue) return;

            if (_selectedCells.Count == 0)
            {
                _selectedCells.Add(_startGridPos.Value);
                _lastProcessedPos = _startGridPos.Value;
                return;
            }

            if (currentPos == _lastProcessedPos) return;

            if (IsAdjacent(currentPos, _lastProcessedPos))
            {
                HandleAdjacentSelection(currentPos);
            }
            else
            {
                HandleJumpSelection(currentPos);
            }

            UpdateSelectionVisual();
        }

        private void HandleAdjacentSelection(Vector2Int currentPos)
        {
            if (_selectedCells.Count > 1 && currentPos == _selectedCells[^2])
            {
                _selectedCells.RemoveAt(_selectedCells.Count - 1);
            }
            else if (!_selectedCells.Contains(currentPos))
            {
                _selectedCells.Add(currentPos);
            }
            _lastProcessedPos = currentPos;
        }

        private void HandleJumpSelection(Vector2Int currentPos)
        {
            Vector2Int direction = currentPos - _lastProcessedPos;
            int steps = Mathf.Max(Mathf.Abs(direction.x), Mathf.Abs(direction.y));
            
            for (int i = 1; i <= steps; i++)
            {
                Vector2Int intermediatePos = new Vector2Int(
                    _lastProcessedPos.x + Mathf.Clamp(direction.x, -1, 1) * i,
                    _lastProcessedPos.y + Mathf.Clamp(direction.y, -1, 1) * i
                );

                if (IsAdjacent(_lastProcessedPos, intermediatePos) && !_selectedCells.Contains(intermediatePos))
                {
                    _selectedCells.Add(intermediatePos);
                    _lastProcessedPos = intermediatePos;
                }
            }
        }

        /// <summary>
        /// 检查并处理符合条件的消除
        /// </summary>
        private async void CheckAndProcessElimination()
        {
            if (_selectedCells.Count < 2) return;

            int totalValue = 0;
            var validCells = new List<CellCtrl_ZeroSum>();

            foreach (var pos in _selectedCells)
            {
                var cell = _matrixCtrl.GetCell<CellCtrl_ZeroSum>(pos);
                if (cell != null)
                {
                    totalValue += cell.Value;
                    validCells.Add(cell);
                }
            }

            if (totalValue == 0 && validCells.Count >= 2)
            {
                await PlayEliminationEffect(validCells);
                
                foreach (var cell in validCells)
                {
                    _matrixCtrl.RemoveCell(cell.CurrentPos);
                }
                
                _matrixCtrl.CompactMatrix(true);
            }
        }

        /// <summary>
        /// 播放消除特效
        /// </summary>
        private async UniTask PlayEliminationEffect(List<CellCtrl_ZeroSum> cells)
        {
            var tasks = new List<UniTask>();
            foreach (var cell in cells)
            {
                tasks.Add(cell.transform.DOScale(0, 0.3f)
                    .SetEase(Ease.InBack)
                    .AsyncWaitForCompletion()
                    .AsUniTask());
            }
            await UniTask.WhenAll(tasks);
        }
        #endregion

        #region Events
        private async void OnClose()
        {
            await _animationHelper.PlayCloseAnimation();
            Close();
        }
        #endregion
    }
}
